-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: TipKit rule triggers an empty_count violation #5918
base: main
Are you sure you want to change the base?
Conversation
e0df3d7
to
e69e152
Compare
Generated by 🚫 Danger |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! Looks good in general, yet we can be even more restrictive in the check for the #Rule
macro.
Source/SwiftLintBuiltInRules/Rules/Performance/EmptyCountRule.swift
Outdated
Show resolved
Hide resolved
Source/SwiftLintBuiltInRules/Rules/Performance/EmptyCountRule.swift
Outdated
Show resolved
Hide resolved
Source/SwiftLintBuiltInRules/Rules/Performance/EmptyCountRule.swift
Outdated
Show resolved
Hide resolved
@@ -62,6 +64,8 @@ struct EmptyCountRule: Rule { | |||
Example("isEmpty && [Int]().isEmpty"), | |||
Example("[Int]().count != 3 && [Int]().↓count != 0 || ↓count == 0 && [Int]().count > 2"): | |||
Example("[Int]().count != 3 && ![Int]().isEmpty || isEmpty && [Int]().count > 2"), | |||
Example("let predicate = #Predicate<SwiftDataModel> { $0.list.↓count == 0 }"): | |||
Example("let predicate = #Predicate<SwiftDataModel> { $0.list.isEmpty }"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of #Predicate<SwiftDataModel>
you may also use any other (simpler) macro that's not #Rule
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the suggestion!
I used "#ExampleMacro" as an example of Macro, referring NoMagicNumberRule.
Or, is it better to use an actual example?(e.g. #Preview?) 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#ExampleMacro
is great. The only reason I was suggesting another name is to keep the examples very simple and reduced down to the significant aspects. Otherwise, the name or its actual existence is not important as long as it's something different than #Rule
to have a valid test case.
What comes to my mind now is that we should also test against #Rule
without any arguments or more than one, the macro with a non-trailing closure, a return statement inside or more than one statement, ...
You can exclude these test cases from appearing in the documentation for simplicity by adding the argument excludeFromDocumentation: true
. Only leave the ones you have now and skip the others as they are not helping users in understanding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice suggestion, let me add the following tests.
- #Rule without any arguments
- #Rule with more than 1 argument
- #Rule with non-trailing closure
- #Rule with multiple trailing closure
- #Rule with a closure with the return statement
- #Rule with a closure with multiple statements.
So far, writing the code of the above test cases with the #Rule macro from the Tips Kit results in a compile error.
However, we added the tests for the following reasons. Do I understand correctly? 🤔
- To cover all the conditional branches introduced in this PR.
- To prepare for the possibility that the #Rule macro might support {no/multiple} {arguments/closures} in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we want to make very sure that the rule only ignores the TipKit #Rule
macro, not any other #Rule
macro. To know for sure, the rule would need full type information. That's expensive, so we try to encode all the syntactic details we know about the macro in order to reduce false positives. That's not 100% even now, but close enough.
The compiler complains about these cases for TipKit's #Rule
macro. There could be other #Rule
macros which are not as strict. We still want to check them.
If you remove import TipKit
and define your own #Rule
macro, the compiler will be happy. That's what you need to imagining as a test setup (without specifying that explicitly).
Makes sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! Thank you for explain it! I'm learning lot from you. 😄
Please rebase your branch to resolve the conflict. |
c63fa72
to
a18f2a4
Compare
a18f2a4
to
3b51ccc
Compare
doSomething() | ||
return $0.donations.isEmpty | ||
} | ||
"""), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To verify the correction mechanism, one test case is enough. We don't need to repeat all of them here again.
resolve #5883
Skip TipKit RuleMacro in EmptyCountRule